package com.springboot.demo.design.pattern.palace;

import com.alibaba.fastjson.JSONObject;
import com.springboot.common.entity.request.ParameterBody;
import com.springboot.common.entity.response.Result;
import com.springboot.demo.design.pattern.form.Form;
import com.springboot.demo.design.pattern.idempotent.IdempotentHelper;
import com.springboot.demo.design.pattern.operator.Practicer;
import lombok.extern.log4j.Log4j2;

/**
 * 标准Palace实现类
 *
 * @author supu
 * @date 2019-03-20 9:41
 **/
@Log4j2
public class StandardPalace implements Palace {
    private Practicer practicer;
    private IdempotentHelper idempotentHelper;

    public StandardPalace(Practicer practicer, IdempotentHelper idempotentHelper) {
        this.practicer = practicer;
        this.idempotentHelper = idempotentHelper;
    }

    @Override
    public <U, V extends ParameterBody> Form<U, V> submit(Form<U, V> form) {
        try {
            if (form.validate()) {
                // 获取幂等结果
                if (idempotentHelper.compareAndGet(form)) {
                    // 重复请求，返回上一次执行成功的结果
                    log.warn("formType:{} 对应的 fromNo:{} 请求重复，上次结果：{}", form.getFormEnum().getValue(),
                            form.getFormNo(), JSONObject.toJSONString(form.getResult()));
                    return form;
                }
                practicer.operate(form);
            } else {
                log.error("parameter:{} 异常, 请检查传入参数", JSONObject.toJSONString(form.getParameter()));
                form.setResult(Result.newFailure("参数异常"));
            }
            return form;
        } catch (Throwable e) {
            log.error("parameter :{} 请求异常：{}", JSONObject.toJSONString(form.getParameter()), e);
            form.setThrowable(e);
            form.setResult(Result.newFailure(e.getMessage()));
        } finally {
            // 保存本次请求结果，幂等需要
            try {
                idempotentHelper.compareAndSet(form);
            } catch (Exception e) {
                log.error("form:{} 保存幂等结果异常：{}", JSONObject.toJSONString(form), e);
            }
            // 消息通知
            // 日志记录
        }

        return form;
    }
}
